package tv.dyndns.kishibe.server.relevance;

import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
import java.util.Set;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.CharArraySet;
import org.apache.lucene.analysis.StopFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.util.Version;

public class ViterbiAnalyzer extends Analyzer {
	public final static String[] STOP_WORDS = { "a", "and", "are", "as", "at", "be", "but", "by",
			"for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "s", "such", "t",
			"that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will",
			"with", "", "www" };

	public static Set<?> getDefaultStopSet() {
		return DefaultSetHolder.DEFAULT_STOP_SET;
	}

	private static class DefaultSetHolder {
		static final Set<?> DEFAULT_STOP_SET = CharArraySet.unmodifiableSet(new CharArraySet(
				LuceneVersion.get(), Arrays.asList(STOP_WORDS), false));
	}

	private final Set<?> stopTable;

	public ViterbiAnalyzer(Version matchVersion) {
		this(matchVersion, DefaultSetHolder.DEFAULT_STOP_SET);
	}

	public ViterbiAnalyzer(Version matchVersion, Set<?> stopwords) {
		stopTable = CharArraySet.unmodifiableSet(CharArraySet.copy(LuceneVersion.get(), stopwords));
	}

	public ViterbiAnalyzer(Version matchVersion, String... stopWords) {
		stopTable = StopFilter.makeStopSet(LuceneVersion.get(), stopWords);
	}

	@Override
	public final TokenStream tokenStream(String fieldName, Reader reader) {
		return new StopFilter(LuceneVersion.get(), new ViterbiTokenizer(reader), stopTable);
	}

	private static class SavedStreams {
		Tokenizer source;
		TokenStream result;
	};

	@Override
	public final TokenStream reusableTokenStream(String fieldName, Reader reader)
			throws IOException {
		/* tokenStream() is final, no back compat issue */
		SavedStreams streams = (SavedStreams) getPreviousTokenStream();
		if (streams == null) {
			streams = new SavedStreams();
			streams.source = new ViterbiTokenizer(reader);
			streams.result = new StopFilter(LuceneVersion.get(), streams.source, stopTable);
			setPreviousTokenStream(streams);
		} else {
			streams.source.reset(reader);
		}
		return streams.result;
	}
}
